package com.r2coding.domain.strategy.service.raffle;

import com.r2coding.domain.strategy.model.entity.RaffleFactorEntity;
import com.r2coding.domain.strategy.model.entity.RuleActionEntity;
import com.r2coding.domain.strategy.model.entity.RuleMatterEntity;
import com.r2coding.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import com.r2coding.domain.strategy.service.rule.IRuleLogicFilter;
import com.r2coding.domain.strategy.service.rule.factory.DefaultLogicFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author caolx
 * @description 抽奖接口实现类
 * @date 2025/8/2 13:34
 */
@Slf4j
@Component
public class DefaultRaffleStrategy extends AbstractRaffleStrategy {

    @Resource
    private DefaultLogicFactory logicFactory;

    @Override
    protected RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> doCheckRaffleBeforeLogic(RaffleFactorEntity raffleFactorEntity, String... logics) {
        if (ArrayUtils.isEmpty(logics)) {
            return RuleActionEntity.<RuleActionEntity.RaffleBeforeEntity>builder()
                    .code(RuleLogicCheckTypeVO.ALLOW.getCode())
                    .info(RuleLogicCheckTypeVO.ALLOW.getInfo())
                    .build();
        }

        Map<String, IRuleLogicFilter<RuleActionEntity.RaffleBeforeEntity>> logicFilterMap = logicFactory.getRaffleBeforeFilterMap();

        // 1、首先校验白名单（最高优先级，VIP用户保障）
        String ruleWhitelist = Arrays.stream(logics)
                .filter(logic -> DefaultLogicFactory.LogicModel.RULE_WHITELIST.getCode().equals(logic) && logicFilterMap.containsKey(logic))
                .findFirst()
                .orElse(null);

        if (StringUtils.isNotBlank(ruleWhitelist)) {
            IRuleLogicFilter<RuleActionEntity.RaffleBeforeEntity> logicFilter = logicFilterMap.get(ruleWhitelist);
            RuleMatterEntity ruleMatterEntity = RuleMatterEntity.builder()
                    .userId(raffleFactorEntity.getUserId())
                    .strategyId(raffleFactorEntity.getStrategyId())
                    .ruleModel(ruleWhitelist)
                    .build();
            RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> ruleActionEntity = logicFilter.filter(ruleMatterEntity);
            log.info("规则过滤-白名单 userId: {}, strategyId: {}, code: {}, info: {}",
                    ruleMatterEntity.getUserId(), ruleMatterEntity.getStrategyId(),
                    ruleActionEntity.getCode(), ruleActionEntity.getInfo());
            if (!RuleLogicCheckTypeVO.ALLOW.getCode().equals(ruleActionEntity.getCode())) {
                return ruleActionEntity;
            }
        }

        // 2、然后校验黑名单（安全控制优先级）
        String ruleBlackList = Arrays.stream(logics)
                .filter(logic -> DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode().equals(logic) && logicFilterMap.containsKey(logic))
                .findFirst()
                .orElse(null);

        if (StringUtils.isNotBlank(ruleBlackList)) {
            IRuleLogicFilter<RuleActionEntity.RaffleBeforeEntity> logicFilter = logicFilterMap.get(ruleBlackList);
            RuleMatterEntity ruleMatterEntity = RuleMatterEntity.builder()
                    .userId(raffleFactorEntity.getUserId())
                    .strategyId(raffleFactorEntity.getStrategyId())
                    .ruleModel(ruleBlackList)
                    .build();
            RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> ruleActionEntity = logicFilter.filter(ruleMatterEntity);
            log.info("规则过滤-黑名单 userId: {}, strategyId: {}, code: {}, info: {}",
                    ruleMatterEntity.getUserId(), ruleMatterEntity.getStrategyId(),
                    ruleActionEntity.getCode(), ruleActionEntity.getInfo());
            if (!RuleLogicCheckTypeVO.ALLOW.getCode().equals(ruleActionEntity.getCode())) {
                return ruleActionEntity;
            }
        }

        // 3、顺序过滤剩余规则（排除已处理的白名单和黑名单）
        List<String> ruleList = Arrays.stream(logics)
                .filter(logic -> !DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode().equals(logic)
                        && !DefaultLogicFactory.LogicModel.RULE_WHITELIST.getCode().equals(logic)
                        && logicFilterMap.containsKey(logic))
                .collect(Collectors.toList());
        RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> ruleActionEntity = null;
        for (String ruleModel : ruleList) {
            IRuleLogicFilter<RuleActionEntity.RaffleBeforeEntity> logicFilter = logicFilterMap.get(ruleModel);

            RuleMatterEntity ruleMatterEntity = RuleMatterEntity.builder()
                    .userId(raffleFactorEntity.getUserId())
                    .strategyId(raffleFactorEntity.getStrategyId())
                    .ruleModel(ruleModel)
                    .build();
            ruleActionEntity = logicFilter.filter(ruleMatterEntity);
            // 非放行结果则顺序过滤
            log.info("抽奖前规则过滤 userId: {}, ruleModel: {}, code: {}, info: {}", raffleFactorEntity.getUserId(), ruleModel,
                    ruleActionEntity.getCode(), ruleActionEntity.getInfo());
            if (!RuleLogicCheckTypeVO.ALLOW.getCode().equals(ruleActionEntity.getCode())) {
                return ruleActionEntity;
            }
        }

        return ruleActionEntity;
    }

    @Override
    protected RuleActionEntity<RuleActionEntity.RaffleCenterEntity> doCheckRaffleCenterLogic(RaffleFactorEntity raffleFactorEntity, String... logics) {
        if (ArrayUtils.isEmpty(logics)) {
            return RuleActionEntity.<RuleActionEntity.RaffleCenterEntity>builder()
                    .code(RuleLogicCheckTypeVO.ALLOW.getCode())
                    .info(RuleLogicCheckTypeVO.ALLOW.getInfo())
                    .build();
        }

        Map<String, IRuleLogicFilter<RuleActionEntity.RaffleCenterEntity>> raffleCenterFilterMap = logicFactory.getRaffleCenterFilterMap();
        List<String> logicCenterRuleList = Arrays.stream(logics)
                .filter(raffleCenterFilterMap::containsKey)
                .collect(Collectors.toList());

        RuleActionEntity<RuleActionEntity.RaffleCenterEntity> ruleActionEntity = null;
        for (String ruleModel : logicCenterRuleList) {
            IRuleLogicFilter<RuleActionEntity.RaffleCenterEntity> logicFilter = raffleCenterFilterMap.get(ruleModel);
            ruleActionEntity = logicFilter.filter(RuleMatterEntity.builder()
                    .userId(raffleFactorEntity.getUserId())
                    .strategyId(raffleFactorEntity.getStrategyId())
                    .awardId(raffleFactorEntity.getAwardId())
                    .ruleModel(ruleModel)
                    .build());

            log.info("抽奖中规则过滤 userId: {}, strategyId: {}, ruleModel: {}, code: {}, info: {}", raffleFactorEntity.getUserId(), raffleFactorEntity.getStrategyId(),
                    ruleModel, ruleActionEntity.getCode(), ruleActionEntity.getInfo());

            if (!RuleLogicCheckTypeVO.ALLOW.getCode().equals(ruleActionEntity.getCode())) {
                return ruleActionEntity;
            }
        }
        return ruleActionEntity;
    }
}
